Dockerイメージをchef-soloでプロビジョニングする
はじめに
DockerでコンテナイメージをbuildするときにはDockerfileにOSイメージの指定や導入パッケージ、実行したいコマンドなどを記述してパッケージングします。
このDockerfileはほぼコマンドべた書きのような形なので難しいわけでは無いのですが、実行処理が多くなればなるほど長く読みづらくしまうし、テストも大変です。また既にChefやPuppet、Ansibleなどの構成管理ツールを用いているのであれば、既存の資産をうまく流用したほうが楽が出来ます。
ということで、Dockerfileにはほとんど仕事をさせずに、Dockerfileからchef-soloをキックしてコンテナをプロビジョニングしてみました。
やってみた
ファイル構成は以下のような形です。今回はopscode謹製のbuild-essentialをレシピとして用意しました。
. ├── Dockerfile └── chef-repo ├── cookbooks │ └── build-essential │ ├── attributes │ ├── libraries │ ├── metadata.json │ ├── metadata.rb │ └── recipes ├── nodes │ └── docker.json └── solo.rb
Dockerfileの内容は以下のとおり。ホスト側の./chef-repoディレクトリをコンテナイメージにADDして、後はchef-soloを実行しているだけです。
FROM centos ENV CHEFHOME /chef-repo ADD chef-repo /chef-repo RUN curl -L http://www.opscode.com/chef/install.sh | bash RUN cd ${CHEFHOME} && chef-solo -c ${CHEFHOME}/solo.rb -j ${CHEFHOME}/nodes/docker.json
chef-repo/solo.rbの内容は以下のとおり、cookbookのパスを指定しているだけです。
file_cache_path "/tmp/chef-solo" cookbook_path ["/chef-repo/cookbooks"]
chef-repo/nodes/docker.jsonで実行したいレシピを指定します。今後セットアップしたい内容が変わったとしてもDockerfileを編集するのではなく、この内容を修正して使いたいレシピを増やしたり減らしたりします。
{ "run_list" : [ "recipe[build-essential]" ] }
ではbuildしてみます。結果は一部省略しています。
$ sudo docker build -t centos:build . Uploading context 62.46 kB Uploading context Step 0 : FROM centos ---> 0b443ba03958 Step 1 : ENV CHEFHOME /chef-repo ---> Using cache ---> 328c5a3b8e71 Step 2 : ADD chef-repo /chef-repo ---> d0cd42db8307 Step 3 : RUN curl -L http://www.opscode.com/chef/install.sh | bash ---> Running in d10235ae7fbb Thank you for installing Chef! ---> d2aa1482b7b9 Step 4 : RUN cd ${CHEFHOME} && chef-solo -c ${CHEFHOME}/solo.rb -j ${CHEFHOME}/nodes/docker.json ---> Running in 92fc0a19bfbd [2014-05-15T05:18:19+00:00] INFO: Forking chef instance to converge... [2014-05-15T05:18:20+00:00] INFO: *** Chef 11.12.4 *** [2014-05-15T05:18:44+00:00] INFO: Setting the run_list to ["recipe[build-essential]"] from CLI options [2014-05-15T05:18:44+00:00] INFO: Run List is [recipe[build-essential]] [2014-05-15T05:18:44+00:00] INFO: Run List expands to [build-essential] [2014-05-15T05:18:44+00:00] INFO: Starting Chef Run for 5cecbeb1290c [2014-05-15T05:18:44+00:00] INFO: Running start handlers [2014-05-15T05:18:44+00:00] INFO: Start handlers complete. ---> 789e47216455 Successfully built 789e47216455 Removing intermediate container 4db1a3f2632a Removing intermediate container d10235ae7fbb Removing intermediate container 92fc0a19bfbd
ちゃんとbuildが通りました!
ではbuildしたイメージを使ってrunしてみます。
$ sudo docker run -i -t centos:build /bin/bash bash-4.1# which gcc /usr/bin/gcc bash-4.1# which autoconf /usr/bin/autoconf
build-essentialに含まれるパッケージがインストールされていることが分かりますね!
まとめ
以上、コネタでした。